/**
 ******************************************************************************
 * @file           : bsp_can.h
 * @brief          : CAN Driver Header File (STM32F4xx)
 ******************************************************************************
 * @attention
 *
 * CAN驱动头文件
 * 支持标准帧和扩展帧
 *
 ******************************************************************************
 */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BSP_CAN_H
#define __BSP_CAN_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "./BSP/CAN/bsp_can_config.h"

/* Exported types ------------------------------------------------------------*/

/**
 * @brief CAN错误码枚举
 */
typedef enum
{
    CAN_OK = 0,                 /*!< 成功 */
    CAN_ERROR_PARAM,            /*!< 参数错误 */
    CAN_ERROR_TIMEOUT,          /*!< 超时错误 */
    CAN_ERROR_BUSY,             /*!< 总线忙 */
    CAN_ERROR_FULL,             /*!< 缓冲区满 */
    CAN_ERROR_EMPTY,            /*!< 缓冲区空 */
    CAN_ERROR_HAL               /*!< HAL库错误 */
} CAN_Error_e;

/**
 * @brief CAN状态枚举
 */
typedef enum
{
    CAN_STATE_IDLE = 0,         /*!< 空闲状态 */
    CAN_STATE_BUSY,             /*!< 忙状态 */
    CAN_STATE_TX,               /*!< 发送状态 */
    CAN_STATE_RX,               /*!< 接收状态 */
    CAN_STATE_ERROR             /*!< 错误状态 */
} CAN_State_e;

/**
 * @brief CAN消息结构体
 */
typedef struct
{
    uint32_t id;                /*!< CAN ID(标准帧11位或扩展帧29位) */
    uint8_t ide;                /*!< 帧类型：0=标准帧, 1=扩展帧 */
    uint8_t rtr;                /*!< 帧格式：0=数据帧, 1=远程帧 */
    uint8_t dlc;                /*!< 数据长度(0-8) */
    uint8_t data[8];            /*!< 数据 */
} CAN_Message_t;

/**
 * @brief CAN接收回调函数类型
 */
typedef void (*can_rx_callback_t)(CAN_Message_t *msg);

/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/* 初始化 */
void can_init(void);
void can_deinit(void);

/* 过滤器配置 */
void can_filter_config(uint32_t id, uint32_t mask);

/* 发送函数 */
uint8_t can_send(const CAN_Message_t *msg);
uint8_t can_send_std(uint32_t id, const uint8_t *data, uint8_t len);
uint8_t can_send_ext(uint32_t id, const uint8_t *data, uint8_t len);

/* 接收函数 */
uint8_t can_receive(CAN_Message_t *msg);
void can_set_rx_callback(can_rx_callback_t callback);

#ifdef __cplusplus
}
#endif

#endif /* __BSP_CAN_H */
